# Level select
#
# Displays buttons for each level.
# Has two next/previous page buttons, each moving to the
# 	next/previous page of levels.
# Each page has different visuals.
# There's also a back button, that goes back to the title screen
#
(class dd_world_level_select dd_world
	(group

	# buttons
	(def dd_meshTexture mesh)
	(def (array dd_meshColour 9) buttonMesh)
	(def (array dd_matrix 9) matrix)

	# constants
	(def int BUTTON_STAGE_START)
	(def int BUTTON_STAGE_END)
	(def int BUTTON_PAGE_NEXT)
	(def int BUTTON_PAGE_PREVIOUS)
	(def int BUTTON_BACK)

	# selection is one of the buttons
	(def int selection)

	# pages and visuals
	(def int page)
	(def int previousPage)
	(def (array float 9) pageColour)

	# animations
	(def float selectionAnimation)
	(def float transitionAnimation)
	(def int transitionAnimationType)
	(def int nextWorld)

	# scale to fit all screen sizes
	(def float scale)

	# create
	(function create (group)
		(group

		# constants
		(= this.BUTTON_STAGE_START 0)
		(= this.BUTTON_STAGE_END 5)
		(= this.BUTTON_PAGE_NEXT 6)
		(= this.BUTTON_BACK 7)
		(= this.BUTTON_PAGE_PREVIOUS 8)

		(dd_meshTexture_create this.mesh)
		(this.mesh.set_primitive DD_PRIMITIVE_RECTANGLE)
		(this.mesh.set_colour 0.5 0.5 0.7)

		(for (def int i this.BUTTON_STAGE_START) (<= i this.BUTTON_STAGE_END) (= i (+ i 1))
			(group
			(dd_matrix_identity this.matrix[i])
			(dd_matrix_translates this.matrix[i] (+ -1.5 (* (% i 3) 1.5)) (+ (/ 1.5 2) (* (/ i 3) -1.5)) 0)

			(dd_meshColour_create this.buttonMesh[i])
			)
		)

		(this.buttonMesh[(+ this.BUTTON_STAGE_START 0)].load "number_1.ply")
		(this.buttonMesh[(+ this.BUTTON_STAGE_START 1)].load "number_2.ply")
		(this.buttonMesh[(+ this.BUTTON_STAGE_START 2)].load "number_3.ply")
		(this.buttonMesh[(+ this.BUTTON_STAGE_START 3)].load "number_4.ply")
		(this.buttonMesh[(+ this.BUTTON_STAGE_START 4)].load "number_5.ply")
		(this.buttonMesh[(+ this.BUTTON_STAGE_START 5)].load "number_6.ply")

		# next page button
		(dd_matrix_identity this.matrix[this.BUTTON_PAGE_NEXT])
		(dd_matrix_rotate_y this.matrix[this.BUTTON_PAGE_NEXT] (dd_math_dec2rad 180))
		(dd_matrix_translates this.matrix[this.BUTTON_PAGE_NEXT] 3 0 0)
		(dd_meshColour_create this.buttonMesh[this.BUTTON_PAGE_NEXT])
		(this.buttonMesh[this.BUTTON_PAGE_NEXT].load "arrow.ply")

		# back button
		(dd_matrix_identity this.matrix[this.BUTTON_BACK])
		(dd_matrix_translates this.matrix[this.BUTTON_BACK] -3 -1.5 0)
		(dd_meshColour_create this.buttonMesh[this.BUTTON_BACK])
		(this.buttonMesh[this.BUTTON_BACK].load "arrow_back.ply")

		# previous page button
		(dd_matrix_identity this.matrix[this.BUTTON_PAGE_PREVIOUS])
		(dd_matrix_translates this.matrix[this.BUTTON_PAGE_PREVIOUS] -3 0 0)
		(dd_meshColour_create this.buttonMesh[this.BUTTON_PAGE_PREVIOUS])
		(this.buttonMesh[this.BUTTON_PAGE_PREVIOUS].load "arrow.ply")

		(= this.selection 0)
		(= this.selectionAnimation 0)

		(= this.transitionAnimation 0)
		(= this.transitionAnimationType 0)

		(= this.page 0)
		(= this.previousPage 0)
		(= this.pageColour[0] 0.1)
		(= this.pageColour[1] 0.1)
		(= this.pageColour[2] 0.1)

		(= this.pageColour[3] 0.6)
		(= this.pageColour[4] 0.2)
		(= this.pageColour[5] 0.2)

		(= this.pageColour[6] 0.2)
		(= this.pageColour[7] 0.8)
		(= this.pageColour[8] 0.2)

		(dd_clearColour this.pageColour[0] this.pageColour[1] this.pageColour[2] 1)

		(= this.scale 1)

		)
	)

	(function resize (group)
		(group

		(def float height)
		(= height (/ (dd_screen_height_get 10) 10))
		(def float width)
		(= width (/ (dd_screen_width_get 10) 16))

		(if (< width height)
			(= this.scale width)
		# else
			(= this.scale height)
		)

		)
	)

	(function update (group)
		(group
		(= this.selectionAnimation (+ this.selectionAnimation 1))

		(if (< this.transitionAnimation 1)
			(group

			# world open animation
			(if (== this.transitionAnimationType 0)
				(group
				(= this.transitionAnimation (+ this.transitionAnimation 0.1))
				)
			# world close animation
			(== this.transitionAnimationType 1)
				(group
				(= this.transitionAnimation (+ this.transitionAnimation 0.1))
				(if (>= this.transitionAnimation 1)
					(if (== this.nextWorld 0)
						(dd_world_set dd_world_menu)
					# else
						(group
						(def int stageIndex (+ (* this.page 6) this.selection))
						(dd_world_set dd_world_game)
						(def (ref dd_world_game) w cworld)
						(w.initStage stageIndex)
						)
					)
				)
				)
			# page transition
			(== this.transitionAnimationType 2)
				(group
				(= this.transitionAnimation (+ this.transitionAnimation 0.1))

				# linearly transform background colour
				(dd_clearColour
					(+ this.pageColour[(+ (* this.previousPage 3) 0)] (* this.transitionAnimation (- this.pageColour[(+ (* this.page 3) 0)] this.pageColour[(+ (* this.previousPage 3) 0)])))
					(+ this.pageColour[(+ (* this.previousPage 3) 1)] (* this.transitionAnimation (- this.pageColour[(+ (* this.page 3) 1)] this.pageColour[(+ (* this.previousPage 3) 1)])))
					(+ this.pageColour[(+ (* this.previousPage 3) 2)] (* this.transitionAnimation (- this.pageColour[(+ (* this.page 3) 2)] this.pageColour[(+ (* this.previousPage 3) 2)])))
				1)
				)
			)

			)
		)

		)
	)

	(function draw (group)
		(group
		(glTranslatef 0 0 -5)

		(for (def int i 0) (< i 9) (= i (+ i 1))
			(group
			(glPushMatrix)
			(glScalef this.scale this.scale this.scale)
			(glMultMatrixf this.matrix[i])
			(if (== this.selection i) (glRotatef this.selectionAnimation 0 1 0))

			# opening world
			(if (== this.transitionAnimationType 0)
				(glScalef this.transitionAnimation this.transitionAnimation this.transitionAnimation)
			# closing world
			(== this.transitionAnimationType 1)
				(glScalef (- 1 this.transitionAnimation) (- 1 this.transitionAnimation) (- 1 this.transitionAnimation))
			(== this.transitionAnimationType 2)
				(group
				(if (&& (>= i this.BUTTON_STAGE_START) (<= i this.BUTTON_STAGE_END))
					(group
					(if (< this.transitionAnimation 0.5)
						(glScalef (+ (* this.transitionAnimation -2) 1)(+ (* this.transitionAnimation -2) 1)(+ (* this.transitionAnimation -2) 1))
					# else
						(glScalef (* (- this.transitionAnimation 0.5) 2)(* (- this.transitionAnimation 0.5) 2)(* (- this.transitionAnimation 0.5) 2))
					)

					)
				)

				)
			)
			(this.buttonMesh[i].draw)
			(glPopMatrix)
			)
		)

		)
	)

	(function key_input (group char key)
		(group

		# next selection
		(if (== key 'd')
			(group
			(= this.selection (+ this.selection 1))
			)
		# previous selection
		(== key 'a')
			(group
			(= this.selection (- this.selection 1))
			)
		# confirm
		(== key ' ')
			(group

			# next page
			(if (== this.selection this.BUTTON_PAGE_NEXT)
				(group
				(if (< this.page 2)
					(group
					(= this.previousPage this.page)
					(= this.page (+ this.page 1))
					(= this.transitionAnimation 0)
					(= this.transitionAnimationType 2)
					)
				)
				)
			# previous page
			(== this.selection this.BUTTON_PAGE_PREVIOUS)
				(group
				(if (> this.page 0)
					(group
					(= this.previousPage this.page)
					(= this.page (- this.page 1))
					(= this.transitionAnimation 0)
					(= this.transitionAnimationType 2)
					)
				)
				)
			# back button
			(== this.selection this.BUTTON_BACK)
				(group
				(= this.transitionAnimation 0)
				(= this.transitionAnimationType 1)
				(= this.nextWorld 0)
				)
			# stage button
			(&& (>= this.selection this.BUTTON_STAGE_START) (<= this.selection this.BUTTON_STAGE_END))
				(group
				(= this.transitionAnimation 0)
				(= this.transitionAnimationType 1)
				(= this.nextWorld 1)
				)
			)
			)
		)

		(if (<  this.selection 0) (= this.selection (+ this.selection 9)))
		(if (>= this.selection 9) (= this.selection (- this.selection 9)))

		)
	)

	)
) ## level_select
